package com.qingxin.sys.support;

import java.io.BufferedReader;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
import java.util.Collections;
import java.util.Hashtable;
import java.util.Map;
import java.util.Properties;

import org.apache.commons.io.FileUtils;

import com.qingxin.sys.utils.ImageUtils;
import com.qingxin.sys.utils.StringUtils;

/**
 * 封装上传文件目录的相关操作【uploadfile.properties】
 * @author Administrator
 *
 */
public class UploadFile {
	/** 上传临时目录 */
	public static final String DIR_TMPDIR = "tmpdir";
	/** 用户头像图片存放目录 */
	public static final String DIR_USER_PHOTO = "user_photo";
	/** 园区图片存放目录 */
	public static final String DIR_FARM_IMG = "farm_img";
	/** 园区地块图片存放目录 */
	public static final String DIR_BLOCK_IMG = "block_img";
	/** 农事活动图片存放目录 */
	public static final String DIR_PRORECORD_IMG = "prorecord_img";
	/** 新闻资讯文章图片 */
	public static final String DIR_NEWS_IMG = "news_img";
	/** ueditor文件上传目录 */
	public static final String DIR_UE_UPLOAD = "ue_upload";

	/** 农作物图片 */
	public static final String DIR_CROP_IMG = "crop_img";
	/** 农作物环节图标 */
	public static final String DIR_PROLINK_IMG = "prolink_img";
	/** 批次产品（追溯物）图片 */
	public static final String DIR_PRODUCTS_IMG = "products_img";
	/** 物资图片 */
	public static final String DIR_MATERIAL_IMG = "material_img";

	/** 名优产品认证图片 */
	public static final String DIR_WELLPRODUCT_IMG = "wellproduct_img";
	
	/** 文章附件 */
	public static final String DIR_CMS_ATTACHMENT = "cms_attachment";
	
	/** 巡查项目附件 */
	public static final String DIR_INSPECTION_ATTACHMENT = "inspection_attachment";

	
	/** 产地环境图片 */
	public static final String DIR_PRO_IMGS = "pro_imgs";
	
	/** 产地环境附件 */
	public static final String DIR_PRO_ATTACHMENT = "pro_attachment";
	
	/** 农资图片 */
	public static final String DIR_REP_IMG = "rep_img";

	/** 特色基地附件 */
	public static final String DIR_PARK_FUJIAN = "park_fujian";
	
	/** 园区视频 */
	public static final String DIR_PARK_VIDEO = "park_video";
	
	/** 企业图片 */
	public static final String DIR_COMPANY_IMG = "company_img";
	
	/** 农资厂商图片 */
	public static final String DIR_MANUFACTURER_IMG = "manufacturer_img";
	
	/** 信用评定附件 */
	public static final String DIR_CREDIT_ATTACHMENT = "credit_attachment";
	
	/** 抽样检测附件 */
	public static final String DIR_CYJC_ATTACHMENT = "cyjc_attachment";
	
	/**
	 * 生成缩略图文件时添加的后缀
	 */
	public static final String THUMB_NAME = "-thumb";
	
	/** 配置文件 */
	//配置文件对象
	private static Properties properties;
	//文件应用路径
	private static String fileroot;
	//文件应用上下文路径 
	private static String fileContentPath;
	//主应用物理路径 
	private static String realpath;
	
	//主机域名
	private static String domain;
	
	//加载配置文件
	private static void load(){
		if(properties != null){
			return;
		}
		properties = new Properties();
		synchronized (properties) {
			try {
				InputStream in = UploadFile.class.getResourceAsStream("/uploadfile.properties");
				BufferedReader reader = new BufferedReader(new InputStreamReader(in, "UTF-8"));
				properties.load(reader);
				in.close();
				reader.close();
				System.out.println("加载文件应用配置[uploadfile.properties]完成.");
				fileroot = properties.getProperty("fileroot");
				fileContentPath = properties.getProperty("fileContentPath");
				domain = properties.getProperty("domain", "");
				if(domain!=null && domain.endsWith("/")){
					domain = domain.substring(0, domain.length()-1);
				}
			} catch (Exception e) {
				System.err.println("加载文件应用配置[uploadfile.properties]出错.");
				throw new RuntimeException(e);
			}
		}
	}
	
	
	/**
	 * 格式化路径
	 * 
	 * @param path
	 * @return
	 */
	public static String formatPath(String path) {
		if(path != null) {
			if(path.startsWith("http://")){
				path = path.substring(7);
				path = path.replaceAll("[\\\\/]+", "/");
				path = "http://" + path;
			}else if(path.startsWith("https://")){
				path = path.substring(8);
				path = path.replaceAll("[\\\\/]+", "/");
				path = "https://" + path;
			}else if(path.startsWith("ftp://")){
				path = path.substring(6);
				path = path.replaceAll("[\\\\/]+", "/");
				path = "ftp://" + path;
			}else{
				path = path.replaceAll("[\\\\/]+", "/");
			}
		}
		return path;
	}
	
	
	/**
	 * 提取文件名
	 * 
	 * @param path
	 * @return
	 */
	public static String getFilename(String path){
		path = formatPath(path);
		return path.substring(path.lastIndexOf("/") + 1);
	}
	
	
	/**
	 * 提取扩展名
	 * 
	 * @param path
	 * @return
	 */
	public static String getExtension(String path){
		return path.substring(path.lastIndexOf(".") + 1);
	}
	
	
	/**
	 * 文件应用路径
	 * @return
	 */
	public static String getFileroot() {
		load();
		return fileroot;
	}
	
	
	/**
	 * 文件应用的上下文路径
	 * @return
	 */
	public static String getFileContentPath() {
		load();
		return fileContentPath;
	}
	
	
	/**
	 * 获取文件应用主机域名
	 * @return
	 */
	public static String getFileDomain(){
		load();
		return domain + fileContentPath;
	}
	
	
	/**
	 * 主机域名
	 * @return
	 */
	public static String getDomain() {
		load();
		return domain;
	}
	
	
	/**
	 * 获取指定文件的访问URL
	 * 
	 * @param filePath 文件相对于系统文件应用的相对路径
	 * @return
	 */
	public static String getFileUrl(String filePath){
		load();
		if(filePath == null) {
			filePath = "";
		}
		if(filePath.length() > 0 && !filePath.startsWith("/")) {
			filePath = "/" + filePath;
		}
		String url = fileContentPath + filePath;
		url = formatPath(url);
		return url;
	}
	
	
	/**
	 * 获取指定文件的访问URL
	 * 
	 * @param filePath 文件目录
	 * @param fileName 文件相对于文件目录的相对路径
	 * @return
	 */
	public static String getFileUrl(String filePath, String fileName){
		if(StringUtils.isEmpty(fileName)){
			return "";
		}
		return getFileUrl(filePath+"/"+fileName);
	}
	
	
	/**
	 * 获取指定文件的访问URL（绝对URL）
	 * @param filePath
	 * @return
	 */
	public static String getFileDomainUrl(String filePath){
		load();
		if(filePath == null) {
			filePath = "";
		}
		if(filePath.length() > 0 && !filePath.startsWith("/")) {
			filePath = "/" + filePath;
		}
		String url = domain + fileContentPath + filePath;
		url = formatPath(url);
		return url;
	}
	
	
	/**
	 * 获取指定文件的访问URL（绝对URL）
	 * 
	 * @param filePath 文件目录
	 * @param fileName 文件相对于文件目录的相对路径
	 * @return
	 */
	public static String getFileDomainUrl(String filePath, String fileName){
		return getFileDomainUrl(filePath+"/"+fileName);
	}
	
	
	/**
	 * 获取应用部署的物理路径
	 * 
	 * @param childPath
	 *            应用下的子路径，以斜线[/]开始，可以为空
	 * @return
	 */
	public static String getRealpath(String childPath) {
		load();
		if(childPath == null) {
			childPath = "";
		}
		if(childPath.length() > 0 && !childPath.startsWith("/")) {
			childPath = "/" + childPath;
		}
		if(StringUtils.isEmpty(realpath)){
			try {
				File file = new File(UploadFile.class.getResource("/").toURI());
				realpath = file.getCanonicalPath();
				realpath = formatPath(realpath);
				realpath = realpath.substring(0, realpath.lastIndexOf("/WEB-INF/"));
			} catch (Exception e) {
			}
		}
		String path = realpath + childPath;
		path = formatPath(path);
		return path;
	}
	
	
	/**
	 * 获取文件应用部署的物理路径
	 * 
	 * @param childPath
	 *            应用下的子路径，以斜线[/]开始，可以为空
	 * @return
	 */
	public static String getFilerootRealpath(String childPath){
		load();
		if(childPath == null) {
			childPath = "";
		}
		if(childPath.length() > 0 && !childPath.startsWith("/")) {
			childPath = "/" + childPath;
		}
		String path = getFileroot() + childPath;
		path = formatPath(path);
		return path;
	}
	
	
	/**
	 * 判断指定文件是否存在
	 * 
	 * @param filePath
	 * @return
	 */
	public static boolean fileExists(String filePath){
		String path = getFilerootRealpath(filePath);
		File file = new File(path);
		return file.isFile();
	}
	
	
	/**
	 * 删除指定文件，如果参数为一个文件则删除并返回true，如果参数为一个目录或不存在，则返回false
	 * 
	 * @param filePath 文件相对于系统文件应用的相对路径
	 * @return
	 */
	public static boolean deleteFile(String filePath){
		String path = getFilerootRealpath(filePath);
		try {
			File file = new File(path);
			if(file.isFile()){
				file.delete();
				//删除缩略图
				String ext = getExtension(path);
				String thumb = path.substring(0, path.lastIndexOf(".")) + THUMB_NAME + "." + ext;
				file = new File(thumb);
				if(file.isFile()){
					file.delete();
				}
				return true;
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
		return false;
	}
	
	
	/**
	 * 删除指定文件，如果参数为一个文件则删除并返回true，如果参数为一个目录或不存在，则返回false
	 * 
	 * @param filePath 文件目录
	 * @param fileName 文件相对于文件目录的相对路径
	 * @return
	 */
	public static boolean deleteFile(String filePath, String fileName){
		return deleteFile(filePath+"/"+fileName);
	}
	
	
	/**
	 * 将指定文件从临时目录转移到目标目录
	 * @param fileName
	 * @param targetDir
	 * @return 目标文件对象
	 */
	public static File moveTmpTo(String fileName, String targetDir){
		File tmpFile = new File(getFilerootRealpath(DIR_TMPDIR+"/"+fileName));
		File targetFile = new File(getFilerootRealpath(targetDir+"/"+fileName));
		if(!targetFile.getParentFile().exists()){
			targetFile.getParentFile().mkdirs();
		}
		try {
			if(tmpFile.isFile()){
				FileUtils.moveFile(tmpFile, targetFile);
			}
		} catch (IOException e) {
			e.printStackTrace();
		}
		return targetFile;
	}
	
	
	/**
	 * 创建图片文件的缩略图
	 * @param imageFile
	 * @return 缩略图文件对象
	 */
	public static File createThumbnail(File imageFile){
		try {
			File thumbnailFile = ImageUtils.createThumbnail(imageFile, 300, 200, THUMB_NAME);
			return thumbnailFile;
		} catch (Exception e) {
			e.printStackTrace();
		}
		return null;
	}
	
	
	/**
	 * 根据图片文件名获取其缩略图文件名
	 * @param imageFilename
	 * @return
	 */
	public static String getThumbnailFilename(String imageFilename){
		String thumbnailFilename = imageFilename.replaceAll("^(.+)(\\.\\w+)$", "$1"+THUMB_NAME+"$2");
		return thumbnailFilename;
	}
	
	
	/**
	 * 获取指定类型文件的存放位置
	 * 
	 * @param key
	 * @return
	 */
	public static String getSaveDirByKey(String key){
		return fileDirMap.get(key);
	}
	
	
	/**
	 * 获取文件目录配置集
	 * 
	 * @return
	 */
	public static Map<String, String> getFileDirMap(){
		return fileDirMap;
	}
	
	
	private static final Map<String, String> fileDirMap;
	static{
		Hashtable<String, String> map = new Hashtable<>();
		
		Field[] fields = UploadFile.class.getFields();
		for(Field field : fields){
			if(!Modifier.isStatic(field.getModifiers())){
				continue;
			}
			String name = field.getName();
			if(!name.startsWith("DIR_")){
				continue;
			}
			try {
				Object val = field.get(null);
				if(val != null){
					String fieldValue = val.toString();
					map.put(fieldValue, fieldValue);
					if(fieldValue.startsWith("/")){
						map.put(fieldValue.substring(1), fieldValue);
					}
				}
			} catch (IllegalArgumentException | IllegalAccessException e) {
				e.printStackTrace();
			}
		}
		fileDirMap = Collections.unmodifiableMap(map);
	}
	
	
}
